package com.realone.packman.codec.decoder;

import com.realone.packman.codec.exception.BmsDecoderException;

import java.nio.ByteBuffer;
import java.security.InvalidParameterException;

/**
 * 解码
 * @author hugx
 * @create 2018-09-12 15:36
 */
public  class BmsDecoder<BmsDecoderDataVo> {

    protected short frameSerialNumber; //帧序号

    protected Integer classType;
    protected byte dataPackageLen; //数据包长度

    /**
     * 解析
     * 模板模式
     * @param data
     * @return
     */
    public BmsDecoderDataVo decoder(byte[] data) {
        if (data == null || data.length == 0) {
            throw new BmsDecoderException(new InvalidParameterException("参数为空"));
        }

        try {
            ByteBuffer bb = ByteBuffer.wrap(data);
            decoderHead(bb);
            BmsDecoderDataVo result = callDecoderStrategy(bb);
            decoderFooter(bb);
            return result;
        } catch (Exception e) {
            throw new BmsDecoderException(e);
        }

    }

    /**
     * 解析头
     * @param bb
     */
    private void decoderHead(ByteBuffer bb) {
         bb.get(); //获取前导
         bb.get(); // 获取分节符
        frameSerialNumber=bb.getShort(); //帧序号
    }

    private BmsDecoderDataVo callDecoderStrategy(ByteBuffer bb){
        byte command  = (byte) (bb.get() & 0xFF);
        this.dataPackageLen=bb.get();
        /* 工厂模式 */
        BmsDecoderStrategy bmsDecoderStrategy=BmsDecoderStrategyFacotry.createBmsDecoderStrategy(command);

        /* 策略模式  */
        return (BmsDecoderDataVo) bmsDecoderStrategy.decoderBody(bb);
    }

    /**
     * 解析尾部
     * @param bb
     */
    private void decoderFooter(ByteBuffer bb) {
        bb.get(); //获取帧结束符
    }

}
